package com.lecyon.farm.service.impl;

import com.aliyun.oss.ClientException;
import com.aliyun.oss.HttpMethod;
import com.aliyun.oss.OSSClient;
import com.aliyun.oss.OSSException;
import com.aliyun.oss.model.*;
import com.google.common.collect.Lists;
import com.lecyon.farm.base.RestResponse;
import com.lecyon.farm.common.constant.CommonConstant;
import com.lecyon.farm.common.constant.FarmSysConstant;
import com.lecyon.farm.service.IObjectStoresConfigService;
import com.lecyon.farm.util.ResultUtil;
import com.lecyon.farm.util.StringHelper;
import com.lecyon.farm.vo.query.QueryFmPictureVo;
import com.lecyon.farm.vo.view.FmPictureInfo;
import com.lecyon.farm.vo.view.ObjectStoresConfigVo;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.net.URL;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDate;
import java.time.ZoneId;
import java.util.Date;
import java.util.List;

/**
 * @author Yao Zheng
 * @Date 2020/4/6 20:28
 */
@Service
@Slf4j
public class FmPictureService {

    private static final Logger LOG = LoggerFactory.getLogger(FmPictureService.class);

    private DateFormat sdf1 = new SimpleDateFormat(CommonConstant.DATE_TIME_FILE_NAME_FORMAT_PATTERN);

    private DateFormat sdf2 = new SimpleDateFormat(CommonConstant.DATE_TIME_FORMAT_PATTERN);

    private LocalDate expirationLocalDate = LocalDate.now().plusYears(1);

    /**
     * 图片处理样式
     */
    private String style = FarmSysConstant.ALI_OSS_PICTURE_STYLE;

    private IObjectStoresConfigService objectStoresConfigService;

    private ObjectStoresConfigVo objectStoresConfigVo;

    @Autowired
    public FmPictureService(IObjectStoresConfigService objectStoresConfigService) {
        this.objectStoresConfigService = objectStoresConfigService;
        objectStoresConfigVo = objectStoresConfigService.getDefault();
    }


    /**
     * 计算图片数量
     *
     * @param vo
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public RestResponse<Integer> countAll(QueryFmPictureVo vo) {
        LOG.info("计算图片数量");
        RestResponse<Integer> result = new RestResponse<>();
        String carId = vo.getCarId();
        String endpoint = objectStoresConfigVo.getEndPoint();
        String accessKeyId = objectStoresConfigVo.getAccessKeyId();
        String accessKeySecret = objectStoresConfigVo.getAccessKeySecret();
        String bucketName = objectStoresConfigVo.getBucketName();
        OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
        LOG.info("Getting Started with OSS SDK for Java");
        try {
            if (!ossClient.doesBucketExist(bucketName)) {
                LOG.info("Creating bucket " + bucketName);
                ossClient.createBucket(bucketName);
                CreateBucketRequest createBucketRequest = new CreateBucketRequest(bucketName);
                createBucketRequest.setCannedACL(CannedAccessControlList.PublicRead);
                ossClient.createBucket(createBucketRequest);
            }
            List<String> carIds = Lists.newArrayList();
            ObjectListing objectListing;
            if (StringHelper.isNotEmpty(carId)) {
                objectListing = ossClient.listObjects(new ListObjectsRequest(bucketName).withPrefix("2019/" + carId));
            } else {
                objectListing = ossClient.listObjects(new ListObjectsRequest(bucketName).withPrefix("2019"));
            }
            for (OSSObjectSummary objectSummary : objectListing.getObjectSummaries()) {
                LOG.info(objectSummary.getKey());
                carIds.add(objectSummary.getKey());
            }
            int count = carIds.size();
            for (int i = 0; i < count; i++) {
                String str = carIds.get(i);
                if (str.substring(str.length() - 1).equals("/")) {
                    count = count - 1;
                }
            }
            return ResultUtil.success(result, count);
        } catch (OSSException oe) {
            LOG.error("Caught an OSSException, which means your request made it to OSS, "
                    + "but was rejected with an error response for some reason.");
            return ResultUtil.error(result, CommonConstant.EX_DB_SELECT_MISS, "查询失败");
        } catch (ClientException ce) {
            LOG.error("Error Message: " + ce.getMessage());
            return ResultUtil.error(result, CommonConstant.EX_DB_SELECT_MISS, "查询失败");
        }
    }

    /**
     * 根据 carId 和 作业时间 查询图片列表
     *
     * @param vo 查询条件
     * @return 查询结果
     */
    public RestResponse<List<FmPictureInfo>> findByCarIdAndWorkDate(QueryFmPictureVo vo) {
        RestResponse<List<FmPictureInfo>> result = new RestResponse<>();
        String endpoint = objectStoresConfigVo.getEndPoint();
        String accessKeyId = objectStoresConfigVo.getAccessKeyId();
        String accessKeySecret = objectStoresConfigVo.getAccessKeySecret();
        String bucketName = objectStoresConfigVo.getBucketName();
        OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
        LOG.info("Getting Started with OSS SDK for Java");
        try {
            if (!ossClient.doesBucketExist(bucketName)) {
                LOG.info("Creating bucket " + bucketName);
                ossClient.createBucket(bucketName);
                CreateBucketRequest createBucketRequest = new CreateBucketRequest(bucketName);
                createBucketRequest.setCannedACL(CannedAccessControlList.PublicRead);
                ossClient.createBucket(createBucketRequest);
            }
            List<FmPictureInfo> carIds = Lists.newArrayList();
            ObjectListing objectListing;
            String carId = vo.getCarId();
            if (StringHelper.isNotEmpty(carId)) {
                objectListing = ossClient.listObjects(new ListObjectsRequest(bucketName).withPrefix("simple_gps/2019/" + carId));
            } else {
                objectListing = ossClient.listObjects(new ListObjectsRequest(bucketName).withPrefix("simple_gps/2019"));
            }
            for (OSSObjectSummary objectSummary : objectListing.getObjectSummaries()) {
                System.out.println(objectSummary.getKey());
                String str = objectSummary.getKey();
                if (!str.substring(str.length() - 1).equals("/")) {
                    GeneratePresignedUrlRequest req = new GeneratePresignedUrlRequest(bucketName, objectSummary.getKey(), HttpMethod.GET);
                    Instant instant = expirationLocalDate.atStartOfDay().atZone(ZoneId.systemDefault()).toInstant();
                    Date expiration = Date.from(instant);
                    req.setExpiration(expiration);
                    req.setProcess(style);
                    URL signedUrl2 = ossClient.generatePresignedUrl(req);
                    System.out.println(signedUrl2);
                    FmPictureInfo fmPictureInfo = new FmPictureInfo();
                    fmPictureInfo.setUrl(signedUrl2.toString());
                    String[] keys = objectSummary.getKey().split("/");
                    fmPictureInfo.setCarId(keys[keys.length - 1].substring(0, 12));
                    try {
                        String time = keys[keys.length - 1].substring(13, keys[keys.length - 1].length() - 5);
                        fmPictureInfo.setTime(sdf2.format(sdf1.parse(time)));
                    } catch (ParseException e) {
                        e.printStackTrace();
                    }
                    carIds.add(fmPictureInfo);
                }
            }
            return ResultUtil.success(result, carIds);
        } catch (OSSException oe) {
            LOG.error("Caught an OSSException, which means your request made it to OSS, "
                    + "but was rejected with an error response for some reason.");
            return ResultUtil.error(result, CommonConstant.EX_DB_SELECT_MISS, "查询失败");
        } catch (ClientException ce) {
            LOG.error("Error Message: " + ce.getMessage());
            return ResultUtil.error(result, CommonConstant.EX_DB_SELECT_MISS, "查询失败");
        }
    }


//    @GetMapping(value = "/pictureInMap")
//    @ResponseBody
//    public String pictureInMap(String carId, String beginTime, String endTime, HttpServletRequest request, HttpServletResponse response) {
//
//        ElasticSearchRead esr = new ElasticSearchRead();
//        List<FmWorkinfo> list = null;
//        try {
//            list = esr.findPhotoByCarId(carId, beginTime, endTime);
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
//        OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
//        System.out.println("Getting Started with OSS SDK for Java\n");
//        try {
//            if (!ossClient.doesBucketExist(bucketName)) {
//                System.out.println("Creating bucket " + bucketName + "\n");
//                ossClient.createBucket(bucketName);
//                CreateBucketRequest createBucketRequest = new CreateBucketRequest(bucketName);
//                createBucketRequest.setCannedACL(CannedAccessControlList.PublicRead);
//                ossClient.createBucket(createBucketRequest);
//            }
//            ObjectListing objectListing = null;
//            for (int i = 0; i < list.size(); i++) {
//                String str = list.get(i).getPicUrl();
//                if (!str.substring(str.length() - 1, str.length()).equals("/")) {
//                    GeneratePresignedUrlRequest req = new GeneratePresignedUrlRequest(bucketName, str, HttpMethod.GET);
//                    req.setExpiration(expiration);
//                    req.setProcess(style);
//                    URL signedUrl2 = ossClient.generatePresignedUrl(req);
//                    list.get(i).setPicUrl(signedUrl2.toString());
//                }
//            }
//            return renderResult(Global.TRUE, "查询成功！", list);
//        } catch (OSSException oe) {
//            System.out.println("Caught an OSSException, which means your request made it to OSS, "
//                    + "but was rejected with an error response for some reason.");
//            return renderResult(Global.TRUE, "查询失败！");
//        } catch (ClientException ce) {
//            System.out.println("Error Message: " + ce.getMessage());
//            return renderResult(Global.TRUE, "查询失败！");
//        }
//    }
//
//
//    @GetMapping(value = "/getPictureList")
//    @ResponseBody
//    @ApiOperation(value = "查询图片列表(G0101)", notes = "根据主机号以及开始时间、结束时间查询图片列表，author:Yao Zheng")
//    public String getPictureListByCarIdAndWorkDate(String carId, String beginTime, String endTime, HttpServletRequest request, HttpServletResponse response) {
//        OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
//        System.out.println("Getting Started with OSS SDK for Java\n");
//        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
//        LocalDateTime beginDateTime = null;
//        LocalDateTime endDateTime = null;
//        if (StringUtils.isNotEmpty(beginTime)) {
//            beginDateTime = LocalDateTime.parse(beginTime, dateTimeFormatter);
//        }
//        if (StringUtils.isNotEmpty(endTime)) {
//            endDateTime = LocalDateTime.parse(endTime, dateTimeFormatter);
//        }
//        //如果开始时间与结束时间同时存在，则需要进行时间的逻辑判断
//        if (null != beginDateTime && null != endDateTime) {
//            if (beginDateTime.isAfter(endDateTime)) {
//                logger.error("开始时间不能晚于结束时间。beginTime : {},endTime : {}", beginTime, endTime);
//                return renderResult(Global.TRUE, "开始时间不能晚于结束时间！", null);
//            }
//        }
//        try {
//            if (!ossClient.doesBucketExist(bucketName)) {
//                System.out.println("Creating bucket " + bucketName + "\n");
//                ossClient.createBucket(bucketName);
//                CreateBucketRequest createBucketRequest = new CreateBucketRequest(bucketName);
//                createBucketRequest.setCannedACL(CannedAccessControlList.PublicRead);
//                ossClient.createBucket(createBucketRequest);
//            }
//            List<FmPictureInfo> carIds = Lists.newArrayList();
//            ObjectListing objectListing;
//            if (carId != null && !carId.equals("")) {
//                objectListing = ossClient.listObjects(new ListObjectsRequest(bucketName).withPrefix("simple_gps/2019/" + carId));
//            } else {
//                objectListing = ossClient.listObjects(new ListObjectsRequest(bucketName).withPrefix("simple_gps/2019"));
//            }
//            LocalDateTime pictureCreateTime;
//            String pictureName;
//            String[] keys;
//            dateTimeFormatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
//            for (OSSObjectSummary objectSummary : objectListing.getObjectSummaries()) {
//                System.out.println(objectSummary.getKey());
//                String str = objectSummary.getKey();
//                if (!str.substring(str.length() - 1).equals("/")) {
//                    GeneratePresignedUrlRequest req = new GeneratePresignedUrlRequest(bucketName, objectSummary.getKey(), HttpMethod.GET);
//                    req.setExpiration(expiration);
//                    req.setProcess(style);
//                    URL signedUrl2 = ossClient.generatePresignedUrl(req);
//                    System.out.println(signedUrl2);
//                    FmPictureInfo fmPictureInfo = new FmPictureInfo();
//                    fmPictureInfo.setUrl(signedUrl2.toString());
//                    keys = objectSummary.getKey().split("/");
//                    fmPictureInfo.setCarId(keys[keys.length - 1].substring(0, 12));
//                    pictureName = keys[keys.length - 1];
//                    keys = pictureName.split("_");
//                    pictureName = keys[keys.length - 1];
//                    keys = pictureName.split("\\.");
//                    String time = keys[0];
//                    if (StringUtils.isEmpty(time)) {
//                        continue;
//                    }
//                    pictureCreateTime = LocalDateTime.parse(time, dateTimeFormatter);
//                    if (null != pictureCreateTime) {
//                        if (null != beginDateTime) {
//                            //如果设定的开始时间不为空，则图片上传时间必须不能早于开始时间
//                            if (pictureCreateTime.isBefore(beginDateTime)) {
//                                continue;
//                            }
//                        }
//                        if (null != endDateTime) {
//                            //如果设定的结束时间不为空，则图片上传时间必须不能晚于结束时间
//                            if (pictureCreateTime.isAfter(endDateTime)) {
//                                continue;
//                            }
//                        }
//                    }
//                    try {
//                        fmPictureInfo.setTime(sdf2.format(sdf1.parse(time)));
//                    } catch (ParseException e) {
//                        e.printStackTrace();
//                    }
//                    carIds.add(fmPictureInfo);
//                }
//            }
//            if (CollectionUtils.isNotEmpty(carIds)) {
//                //排序
//                Collections.sort(carIds);
//                //反转整个数组
//                Collections.reverse(carIds);
//            }
//            return renderResult(Global.TRUE, "查询成功！", carIds);
//        } catch (OSSException oe) {
//            System.out.println("Caught an OSSException, which means your request made it to OSS, "
//                    + "but was rejected with an error response for some reason.");
//            return renderResult(Global.TRUE, "查询失败！");
//        } catch (ClientException ce) {
//            System.out.println("Error Message: " + ce.getMessage());
//            return renderResult(Global.TRUE, "查询失败！");
//        }
//    }
//
//    @PostMapping(value = "/easy/upload")
//    @ResponseBody
//    public String upload(@RequestBody String content, String carId, String fileName, String checkSum, HttpServletRequest request, HttpServletResponse response) {
//        ServletInputStream ss1 = null;
//        try {
//            ss1 = request.getInputStream();
//            System.out.println(ss1);
//        } catch (IOException e) {
//            e.printStackTrace();
//        }
//        OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
//        System.out.println("Getting Started with OSS SDK for Java\n");
//        try {
//            String str = content;
//            byte[] sb = str.getBytes();
//            int a = 0;
//            for (int i = 0; i < sb.length; i++) {
//                a += sb[i];
//                if (a >= 256) {
//                    a = a - 256;
//                }
//            }
//            log.info("本地校验位十进制是：------" + a + "----------");
//            log.info("接受校验位十六进制是：------" + checkSum + "----------");
//            int checkByte = Integer.parseInt(checkSum, 16);
//            log.info("接受校验位十进制是：------" + checkByte + "----------");
//            if (a == checkByte) {
//                byte[] data = new byte[str.length() / 2];
//                for (int i = 0; i < str.length() / 2; i++) {
//                    String ss = str.substring(i * 2, i * 2 + 2);
//                    byte res = (byte) Integer.parseInt(ss, 16);
//                    data[i] = res;
//                }
//                log.info("图片数据长度为：------" + data.length + "----------");
//                log.info(fileName + "开始图片上传");
//                // <yourObjectName>表示上传文件到OSS时需要指定包含文件后缀在内的完整路径，例如abc/efg/123.jpg。
//                PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, DateUtils.getYear() + "/" + carId + "/" + fileName, new ByteArrayInputStream(data));
////            PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, key, new File("C:\\Users\\11385\\Desktop\\nav_7.png"));
//
//                // 如果需要上传时设置存储类型与访问权限，请参考以下示例代码。
//                // ObjectMetadata metadata = new ObjectMetadata();
//                // metadata.setHeader(OSSHeaders.OSS_STORAGE_CLASS, StorageClass.Standard.toString());
//                // metadata.setObjectAcl(CannedAccessControlList.Private);
//                // putObjectRequest.setMetadata(metadata);
//
//                // 上传字符串。
//                ossClient.putObject(putObjectRequest);
//
//                log.info(fileName + "图片上传结束");
//                // 关闭OSSClient。
//                ossClient.shutdown();
//                return renderResult(Global.TRUE, "ok");
//            } else {
//
//                log.info(fileName + "校验出错");
//                return renderResult(Global.FALSE, "error");
//            }
//
//
//        } catch (OSSException oe) {
//            System.out.println("Caught an OSSException, which means your request made it to OSS, "
//                    + "but was rejected with an error response for some reason.");
//            return renderResult(Global.FALSE, "error");
//        } catch (ClientException ce) {
//            System.out.println("Error Message: " + ce.getMessage());
//            return renderResult(Global.FALSE, "error");
//        }
//    }

    /**
     * ----------------------------- 分割线 以下是setter方法，用于替换field上的@Autowired -----------------------------
     **/

}
